package org.xx.armory.spring5.mvc.captchacode;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.util.Pair;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Properties;
import java.util.Random;

public class KaptchaCodeImageProvider
        implements CaptchaCodeImageProvider {
    /**
     * <strong>不使用下列字符，因为它们变形后不易辨认 'l', 'L', 'O', 'o', '0' etc... </strong>
     */
    private static final char[] CODE_SET = {'a', 'c', 'd', 'f', 'g', 'h',
            'k', 'p', 'x', 'y', '2', '3', '5', '6', '7', '8'};

    @Value("${armory.mvc.captcha-code-image.code-length:6}")
    private int codeLength;

    @Value("${armory.mvc.captcha-code-image.width:102}")
    private int width;

    @Value("${armory.mvc.captcha-code-image.height:38}")
    private int height;

    /**
     * 创建一个缺省的配置。
     *
     * @return 缺省的配置。
     */
    @SuppressWarnings("SpellCheckingInspection")
    private static Properties createDefaultConfig() {
        final Properties props = new Properties();
        props.setProperty("kaptcha.border", "no");
        props.setProperty("kaptcha.textproducer.font.names", "Arial");
        props.setProperty("kaptcha.textproducer.font.size", "24");
        props.setProperty("kaptcha.textproducer.char.space", "1");
        // props.setProperty("kaptcha.obscurificator.impl",
        // "com.google.code.kaptcha.impl.ShadowGimpy");
        props.setProperty("kaptcha.obscurificator.impl", SimpleGimpy.class.getName());
        props.setProperty("kaptcha.noise.impl", SimpleNoise.class.getName());
        return props;
    }

    @Override
    public Pair<String, BufferedImage> createCodeAndImage()
            throws IOException {
        final var rnd = new Random();

        // 生成随机码。
        final var captchaCodeBuilder = new StringBuilder();
        for (var i = 0; i < this.codeLength; ++i) {
            captchaCodeBuilder.append(CODE_SET[rnd.nextInt(CODE_SET.length)]);
        }
        final var captchaCode = captchaCodeBuilder.toString();

        final com.google.code.kaptcha.Producer producer = new com.google.code.kaptcha.impl.DefaultKaptcha();
        final Properties props = new Properties(ConfigHolder.INSTANCE);
        props.setProperty("kaptcha.image.width", String.valueOf(width));
        props.setProperty("kaptcha.image.height", String.valueOf(height));
        ((com.google.code.kaptcha.util.Configurable) producer).setConfig(
                new com.google.code.kaptcha.util.Config(props));

        return Pair.of(captchaCode, producer.createImage(captchaCode));
    }

    private static class ConfigHolder {
        /**
         * 缺省配置实例
         */
        static final Properties INSTANCE = createDefaultConfig();
    }
}
